package com.rtsapp.server.network.session.netty;

import com.rtsapp.server.logger.LoggerFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.util.AttributeKey;

import java.net.InetSocketAddress;

import com.rtsapp.server.network.session.Session;
import com.rtsapp.server.logger.Logger;


public class NettySession  implements Session{

	private static final Logger LOGGER = LoggerFactory.getLogger(NettySession.class);

	private final Channel channel;
	private final SessionType type;
	private final long sessionId;
	private long remoteId = -1L;
	
	private boolean isClosed = false;
	
	private final NettySessionManager sessionMannager;


	NettySession( NettySessionManager sessionManager, Channel channel, SessionType type, long sessionId ){
		this.sessionMannager = sessionManager;
		this.channel = channel;
		this.type = type;
		this.sessionId = sessionId;
	}

	@Override
	public Channel getChannel(){
		return channel;
	}


	@Override
	public SessionType getType() {
		return type;
	}

	@Override
	public long getSessionId() {
		return this.sessionId;
	}

	@Override
	public long getRemoteId() {
		return remoteId;
	}

	@Override
	public void setRemoteId(long remoteId) {
		this.remoteId = remoteId;

		sessionMannager.bindSessionRemoteId( this, remoteId );
	}


	@Override
	public void write(Object message) {
		send(message);
	}

	public void flush(){
		channel.flush();
	}

	@Override
	public void send(Object message) {
		channel.writeAndFlush(message);
	}


	/**
	 * 发送数据，发送完毕后，关闭连接
	 * @param message
	 */
	public void sendAndClose( Object message ){

		ChannelFuture f = channel.writeAndFlush(message);
		f.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				if ( future.isSuccess() ) {
					LOGGER.debug( "sendAndClose 成功完成，关闭channel" );
					close();
				} else {
					LOGGER.error( "sendAndClose 未完成，关闭channel" );
					close();
				}
			}
		});
	}

	/**
	 * 关闭Channel
	 * 1. 主动关闭
	 * 		* 移除
	 */
	@Override
	public void close(){
		LOGGER.info( "session.close 关闭channel, channel.hasCode={},channel={}", channel.hashCode(), channel );
		channel.close();
	}

	@Override
	public void setAttribute( String key, Object object ) {
		channel.attr( AttributeKey.valueOf( key ) ).set( object );
	}

	@Override
	public Object getAttribute(String key) {
		return channel.attr( AttributeKey.valueOf( key ) ).get( );
	}

	@Override
	public void removeAttribute(String key) {
		channel.attr( AttributeKey.valueOf( key) ).remove();
	}

	@Override
	public InetSocketAddress getRemoteAddress() {
		return (InetSocketAddress)channel.remoteAddress();
	}

	@Override
	public InetSocketAddress getLocalAddress() {
		return (InetSocketAddress)channel.localAddress();
	}

}
